package com.kehutong.admin.service;

import com.kehutong.admin.entity.BusinessTag;
import com.kehutong.common.DoveClient;
import com.kehutong.common.entity.Root;
import org.coraframework.authz.Subject;
import org.coraframework.authz.SubjectUtil;
import org.coraframework.inject.Inject;
import org.coraframework.json.JSONArray;
import org.coraframework.json.JSONObject;
import org.coraframework.logger.Logger;
import org.coraframework.logger.LoggerFactory;
import org.coraframework.mvc.http.Bean;
import org.coraframework.mvc.http.ReqMapping;
import org.coraframework.mvc.http.result.Result;
import org.coraframework.mvc.webservice.WebService;
import org.coraframework.orm.Pool;
import org.coraframework.orm.jdbc.JdbcSession;
import org.coraframework.orm.jdbc.Page;
import org.coraframework.orm.jdbc.execute.entity.FindOne;
import org.coraframework.orm.jdbc.execute.entity.FindPage;
import org.coraframework.util.IDGenerate;
import org.coraframework.util.Objects;
import org.coraframework.util.UUIDGenerator;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 业务标签服务类
 *
 * @author: liukunlong
 * @date: 2021-07-28 10:08
 */
@WebService("/admin/business/tag/service")
public class BusinessTagService {

    static final Logger logger = LoggerFactory.getLogger(BusinessTagService.class);


    @Inject
    private JdbcSession jdbcSession;


    @Inject
    private DoveClient doveClient;


    /**
     * 如果没有就新增标签组及标签(批量打业务标签--=)
     *
     * @param jsonObject 查询对象
     * @return
     * @throws Exception
     */
    @ReqMapping("/batch/add")
    public Object batchAdd(JSONObject jsonObject) throws Exception {
        List<BusinessTag> result=new ArrayList<>();
        JSONArray dataList=jsonObject.getJSONArray("dataList");
        if (Objects.nonEmpty(dataList)) {
            for (Object dataObj : dataList) {
                JSONObject data = (JSONObject) dataObj;
                result.addAll(add(data));
            }
        }
       return result;
    }

    private List<BusinessTag> add(JSONObject jsonObject){
        List<BusinessTag> result=new ArrayList<>();
        String tagGroupName = jsonObject.getString("tagGroupName");
        String tagName = jsonObject.getString("tagName");
        String[] tagNames=tagName.split(",");
        FindOne<BusinessTag> findTagGroup = jdbcSession.findOne(BusinessTag.class)
                .eq("name", tagGroupName)
                .eq("group", true)
                .eq("deleted", false);
        BusinessTag businessTagGroup = findTagGroup.exe();
        //如果标签组为空则新增标签组及标签
        if (Objects.isNull(businessTagGroup)) {
            businessTagGroup = Pool.newInstance(BusinessTag.class, UUIDGenerator.randomUUID());
            businessTagGroup.setPid(Root.ROOT_ID);
            businessTagGroup.setGroup(true);
            businessTagGroup.setName(tagGroupName);
            businessTagGroup.setCreateBy(Root.ROOT_ID);
            businessTagGroup.setCreateName("系统");
            businessTagGroup.setSort(System.currentTimeMillis());
            jdbcSession.insert(businessTagGroup);
            for (String name : tagNames) {
                BusinessTag businessTag = Pool.newInstance(BusinessTag.class, UUIDGenerator.randomUUID());
                businessTag.setPid(businessTagGroup.getId());
                businessTag.setPname(businessTagGroup.getName());
                businessTag.setGroup(false);
                businessTag.setName(name);
                businessTag.setCreateBy(Root.ROOT_ID);
                businessTag.setCreateName("系统");
                businessTag.setSort(System.currentTimeMillis());
                jdbcSession.insert(businessTag);
                result.add(businessTag);
            }
            return result;
        }

        for (String name : tagNames) {
            //如果标签为空则新增
            FindOne<BusinessTag> findTag = jdbcSession.findOne(BusinessTag.class)
                    .eq("pid",businessTagGroup.getId())
                    .eq("name", name)
                    .eq("group", false)
                    .eq("deleted", false);
            BusinessTag businessTag = findTag.exe();
            if (Objects.isNull(businessTag)) {
                businessTag = Pool.newInstance(BusinessTag.class, UUIDGenerator.randomUUID());
                businessTag.setPid(businessTagGroup.getId());
                businessTag.setPname(businessTagGroup.getName());
                businessTag.setGroup(false);
                businessTag.setName(name);
                businessTag.setCreateBy(Root.ROOT_ID);
                businessTag.setCreateName("系统");
                businessTag.setSort(System.currentTimeMillis());
                jdbcSession.insert(businessTag);
                result.add(businessTag);
            }else{
                //修改业务标签组名称为空
                businessTag.setPname(businessTagGroup.getName());
                result.add(businessTag);
            }

        }
        return result;
    }


    /**
     * 根据条件获取标签列表
     *
     * @param jsonObject 查询对象
     * @return 标签列表
     * @throws IOException 操作异常
     */
    @ReqMapping("/page")
    public Page<BusinessTag> page(JSONObject jsonObject) throws Exception {
        String tagName = jsonObject.getString("tagName");

        Page<BusinessTag> result = null;
        FindPage<BusinessTag> findPage = jdbcSession.findPage(BusinessTag.class)
                .eq(jsonObject, "id", "pid")
                .like(jsonObject, "name")
                .eq("group", false)
                .eq("deleted", false)
                .order("sort", "desc")
                .page(jsonObject);
        JSONArray idsArray=jsonObject.getJSONArray("ids");
        if(Objects.nonEmpty(idsArray)){
            findPage.in("id",idsArray);
        }
        result = findPage.exe();
        if (logger.isDebugEnabled()) {
            logger.debug("result:" + result);
        }
        if (Objects.nonNull(result)) {
            List<BusinessTag> businessTagList = result.getList();
            JSONObject condition = new JSONObject();
            Subject subject = SubjectUtil.getSubject();
            for (BusinessTag businessTag : businessTagList) {
                condition.put("tagNo", businessTag.getId());
                if (!Root.isRoot(subject.getUserId())) {
                    Long useCount = getUseTagCount(condition);
                    businessTag.setUseCount(useCount);
                }
                BusinessTag businessTagGroup = jdbcSession.findById(BusinessTag.class, businessTag.getPid());
                if (Objects.nonNull(businessTagGroup)) {
                    businessTag.setPname(businessTagGroup.getName());
                } else {
                    businessTag.setPname("");
                }
            }
        }
        return result;
    }

    /**
     * 获取标签列表
     *
     * @param jsonObject 查询对象
     * @return
     * @throws Exception
     */
    @ReqMapping("/list")
    public Object list(JSONObject jsonObject) throws Exception {
        jsonObject.put("pageNo", 1);
        jsonObject.put("pageSize", Short.MAX_VALUE);
        Page<BusinessTag> page = page(jsonObject);
        return page.getList();
    }

    /**
     * 获取标签内容
     *
     * @param businessTag 标签对象
     * @return
     */
    @ReqMapping("/get")
    public Object get(BusinessTag businessTag) {
        return businessTag;
    }

    /**
     * 保存标签
     *
     * @param businessTag 系统标签对象
     * @return
     */
    @Bean(newInstance = true, copy = true)
    @ReqMapping("/save")
    public Object save(BusinessTag businessTag) {
        String id = businessTag.getId();
        BusinessTag dbBusinessTag = jdbcSession.findOne(BusinessTag.class)
                .eq("deleted", false)
                .eq("group", false)
                .markBegin()
                .eq("id", id).or()
                .eq("name", businessTag.getName()).or()
                .markEnd().exe();
        if (Objects.isNull(dbBusinessTag)) {
            businessTag.setGroup(false);
            businessTag.setSort(System.currentTimeMillis());
            businessTag.setCreateBy(Root.ROOT_ID);
            businessTag.setCreateName("系统");
            jdbcSession.insert(businessTag);
        } else {
            dbBusinessTag.setName(businessTag.getName());
            businessTag.setCreateBy(Root.ROOT_ID);
            businessTag.setCreateName("系统");
            jdbcSession.updateById(dbBusinessTag);
        }
        return Result.success();
    }

    /**
     * 更新标签
     *
     * @param businessTag 系统标签对象
     * @return
     * @throws Exception
     */
    @Bean(copy = true)
    @ReqMapping("/update")
    public Object update(BusinessTag businessTag) throws Exception {
        String id = businessTag.getId();
        BusinessTag dbBusinessTag = jdbcSession.findOne(BusinessTag.class)
                .eq("group", false)
                .eq("deleted", false)
                .eq("id",id).exe();
        if (Objects.isNull(dbBusinessTag)) {
            return Result.success("0", "标签不存在");
        }
        jdbcSession.updateById(businessTag);
        return Result.success();
    }


    /**
     * 删除标签
     *
     * @param businessTag 标签对象
     * @return
     */
    @ReqMapping("/delete")
    public Object delete(BusinessTag businessTag) {
        businessTag.setDeleted(true);
        jdbcSession.updateById(businessTag);
        return Result.success();
    }

    /**
     * 根据条件获取标签组分页列表
     *
     * @param jsonObject 查询对象
     * @return 住户汽车列表
     * @throws IOException 操作异常
     */
    @ReqMapping("/group/page")
    public Page<BusinessTag> groupPage(JSONObject jsonObject) throws Exception {
        String tagName = jsonObject.getString("tagName");

        Page<BusinessTag> result = null;
        FindPage<BusinessTag> findPage = jdbcSession.findPage(BusinessTag.class)
                .eq(jsonObject, "id")
                .like(jsonObject, "name")
                .eq("group", true)
                .eq("deleted", false)
                .order("sort", "desc")
                .page(jsonObject);
        if (Objects.nonEmpty(tagName)) {
            List<BusinessTag> businessTagList = jdbcSession.findArray(BusinessTag.class)
                    .eq("group", false)
                    .eq("deleted", false)
                    .like("name", tagName).exe();
            List<String> ids = businessTagList.stream().map(BusinessTag::getPid).collect(Collectors.toList());
            if (Objects.nonEmpty(ids)) {
                findPage.in("id", ids);
            }
        }
        result = findPage.exe();
        if (logger.isDebugEnabled()) {
            logger.debug("result:" + result);
        }
        if (Objects.nonNull(result)) {
            List<BusinessTag> businessTagGroupList = result.getList();
            for (BusinessTag businessGroupTag : businessTagGroupList) {
                List<BusinessTag> businessTagList = jdbcSession.findArray(BusinessTag.class)
                        .eq("pid", businessGroupTag.getId())
                        .eq("group", false)
                        .eq("deleted", false)
                        .order("sort", "desc")
                        .exe();

                //设置标签的组名称
                for (BusinessTag businessTag : businessTagList) {
                    businessTag.setPname(businessGroupTag.getName());
                }
                businessGroupTag.setChildList(businessTagList);

            }
        }
        return result;
    }

    /**
     * 根据条件获取标签组列表
     *
     * @param jsonObject 查询对象
     * @return
     * @throws Exception
     */
    @ReqMapping("/group/list")
    public Object groupList(JSONObject jsonObject) throws Exception {
        jsonObject.put("pageNo", 1);
        jsonObject.put("pageSize", Short.MAX_VALUE);
        Page<BusinessTag> page = groupPage(jsonObject);
        return page.getList();
    }

    /**
     * 获取标签组
     *
     * @param businessTagGroup 系统标签对象
     * @return
     */
    @ReqMapping("/group/get")
    public Object groupGet(BusinessTag businessTagGroup) {
        if (Objects.nonNull(businessTagGroup)) {
            List<BusinessTag> businessTagList = jdbcSession.findArray(BusinessTag.class)
                    .eq("pid", businessTagGroup.getId())
                    .eq("group", false)
                    .eq("deleted", false)
                    .order("sort", "desc")
                    .exe();
            businessTagGroup.setChildList(businessTagList);

        }
        return businessTagGroup;
    }

    /**
     * 保存标气标签组及标签
     *
     * @param businessTagGroup 系统标签对象
     * @return
     */
    @Bean(newInstance = true, copy = true)
    @ReqMapping("/group/save")
    public Object groupSave(BusinessTag businessTagGroup) {
        String id = businessTagGroup.getId();
        BusinessTag dbBusinessTagGroup = jdbcSession.findOne(BusinessTag.class)
                .eq("deleted", false)
                .eq("group", true)
                .markBegin()
                .eq("id", id).or()
                .eq("name", businessTagGroup.getName()).or()
                .markEnd().exe();
        if (Objects.isNull(dbBusinessTagGroup)) {
            businessTagGroup.setPid(Root.ROOT_ID);
            businessTagGroup.setGroup(true);
            businessTagGroup.setSort(System.currentTimeMillis());
            jdbcSession.insert(businessTagGroup);
        } else {
            throw new RuntimeException("标签组不能重复");
           /* dbBusinessTagGroup.setName(businessTagGroup.getName());
            jdbcSession.updateById(dbBusinessTagGroup);*/
        }
        List<BusinessTag> businessTagList = businessTagGroup.getChildList();
        if (Objects.nonNull(businessTagList)) {
            for (BusinessTag businessTag : businessTagList) {
                businessTag.setId(IDGenerate.uuid());
                businessTag.setPid(businessTagGroup.getId());
                businessTag.setGroup(false);
                businessTag.setCreateBy(Root.ROOT_ID);
                businessTag.setCreateName("系统");
            }
        }
        jdbcSession.insert(businessTagList);
        return Result.success();
    }

    /**
     * 更新标签组及标签
     *
     * @param businessTagGroup 系统标签对象
     * @return
     * @throws Exception
     */
    @Bean(copy = true)
    @ReqMapping("/group/update")
    public Object groupUpdate(BusinessTag businessTagGroup) throws Exception {
        String id = businessTagGroup.getId();
        BusinessTag dbBusinessTagGroup = jdbcSession.findOne(BusinessTag.class)
                .eq("deleted", false)
                .markBegin()
                .eq("id", id).or()
                .eq("name", businessTagGroup.getName()).or()
                .markEnd().exe();
        if (Objects.isNull(dbBusinessTagGroup)) {
            return Result.success("0", "标签组不存在");
        }
        jdbcSession.updateById(businessTagGroup);


        //输入的标签集合
        List<BusinessTag> businessTagList = businessTagGroup.getChildList();

        Map<String, BusinessTag> mapping = new HashMap<>();
        for (BusinessTag businessTag : businessTagList) {
            if (Objects.nonEmpty(businessTag.getId())) {
                mapping.put(businessTag.getId(), businessTag);
            }
        }


        //数据库已存在的标签集合
        List<BusinessTag> dbBusinessTagList = jdbcSession.findArray(BusinessTag.class)
                .eq("pid", dbBusinessTagGroup.getId())
                .eq("group", false)
                .eq("deleted", false)
                .order("sort", "desc")
                .exe();


        //需要更新的标签集合
        List<BusinessTag> updateBusinessTagList = new ArrayList<>();

        //需要删除的标签集合
        List<BusinessTag> deleteBusinessTagList = new ArrayList<>();

        for (BusinessTag dbBusinessTag : dbBusinessTagList) {
            String dbId = dbBusinessTag.getId();
            if (mapping.containsKey(dbId)) {
                updateBusinessTagList.add(mapping.get(dbId));
                businessTagList.remove(dbBusinessTag);
            } else {
                deleteBusinessTagList.add(dbBusinessTag);
            }
        }

        //需要新增的标签集合
        List<BusinessTag> addBusinessTagList = new ArrayList<>(businessTagList);

        //增量新增标签
        if (Objects.nonEmpty(addBusinessTagList)) {
            for (BusinessTag businessTag : addBusinessTagList) {
                businessTag.setId(IDGenerate.uuid());
                businessTag.setPid(dbBusinessTagGroup.getId());
                businessTag.setGroup(false);
                businessTag.setCreateBy(Root.ROOT_ID);
                businessTag.setCreateName("系统");
            }
            jdbcSession.insert(addBusinessTagList);
        }

        //增量更新标签
        if (Objects.nonEmpty(updateBusinessTagList)) {
            jdbcSession.updateById(updateBusinessTagList);
        }

        //增量删除标签
        if (Objects.nonEmpty(deleteBusinessTagList)) {
            for (BusinessTag businessTag : deleteBusinessTagList) {
                businessTag.setDeleted(true);
            }
            jdbcSession.updateById(deleteBusinessTagList);
        }
        return Result.success();
    }


    /**
     * 删除标签组及标签
     *
     * @param businessTagGroup 系统标签组对象
     * @return
     */
    @ReqMapping("/group/delete")
    public Object groupDelete(BusinessTag businessTagGroup) {
        businessTagGroup.setDeleted(true);
        jdbcSession.updateById(businessTagGroup);
        if (businessTagGroup.isGroup()) {
            List<BusinessTag> businessTagList = jdbcSession.findArray(BusinessTag.class)
                    .eq("pid", businessTagGroup.getId())
                    .eq("group", false)
                    .eq("deleted", false)
                    .order("sort", "desc")
                    .exe();
            if (Objects.nonEmpty(businessTagList)) {
                for (BusinessTag businessTag : businessTagList) {
                    businessTag.setDeleted(true);
                }
                jdbcSession.updateById(businessTagList);
            }
        }
        return Result.success();
    }


    private Long getUseTagCount(JSONObject jsonObject) throws Exception {
        JSONObject systemTagResult = doveClient.post("/crm/user/tag/service/count", http -> {
            http.setBody(jsonObject.toJSONString());
        });
        JSONObject rs = systemTagResult.getJSONObject("data");
        return rs.getLongValue("count");
    }

}
